1. CPU Utilization View
CPU Utilization view displays utilization of the logical cores in the
system. Logical cores include virtual cores from solutions such as
hyperthreading.
In the preceding graphic, the y-axis represents the logical cores,
and the x-axis is the timeline, shown in milliseconds. There is a Zoom
slider control above the graph. Drag right to enlarge the graph. You can
also drag the mouse horizontally across the graph to zoom in to a
portion of the graph.
Each color on the graph indicates a type of process and its relative
CPU utilization. The legend explains the purpose of each color.
-
Green indicates the CPU utilization of the current application.
-
Yellow shows CPU utilization for other applications.
-
Red is the percentage of CPU utilization accorded to the system.
-
Gray shows idle processor cores.
If in doubt, you can point to an area of the graph to see a tooltip
that provides information on that portion of the graph. For example, if
you point to the green portion of the graph, the name and process
identifier for the current process displays.
CPU Utilization view is good for exposing a variety of problems,
including low CPU utilization, which could be an indicator of deadlocks
or over-synchronization. You can even spot excessive CPU utilization
from other applications competing for processor resources.
The
Threads view provides the most information of the three views. There
are several regions to the Threads view, as depicted in the following
graphic.
The central region is a graph, where the x-axis is a timeline in
milliseconds. The y-axis presents mixed information. The top two rows
are disk-read and disk-write activity. The remaining rows are threads.
These rows are labeled with a brief description and the thread
identifier. The various color segments in the bar graph indicate
execution status. For example, green indicates a running thread. The
Visible Timeline Profile has an explanation of each category. It also
shows the percentage of time spent in each of these categories.
The execution categories are:
-
Execution
. The thread is running unimpeded.
-
Synchronization
. The thread is blocked for synchronization. The
Concurrency Visualizer will attempt to identify the source of the
synchronization.
-
I/O
. The thread is blocking on an input/output event.
-
Sleep
. The thread voluntarily yields the CPU. Thread.Sleep is the most common method for yielding the CPU.
-
Memory Management
. The thread is incurring blocking events related to memory-related activities, such as page faults.
-
Preemption
. The thread is preempted by another thread. For example, this would occur when a higher-priority thread starts running.
-
UI Processing
. The
user interface has a message pump, which handles messages for the main
window. For a responsive user interface, the message pump is typically
idle while waiting to respond to the next user interface message. This
category indicates the amount of work the user interface thread is
performing in response to user interface requests.
You can sort the threads in the graph on these categories. The sort button appears above and to the left of the graph.
A segment is a contiguous region in one category of execution. You
can point to a segment for additional information. You’ll see different
information depending on the category. As shown in the following graphic
for preemption, the replacing thread, the delay, and other information
is displayed in the tooltip.
You can also select segments in the graph. When you click a segment
to select it, the selection enlarges for emphasis. In addition, some
regions of the graph are in the context of the selected segment, such as
the Current stack and Unblocking stack results.
As with CPU Utilization view, you can enlarge the entire graph by
using the Zoom slider control or by dragging horizontally to zoom in to a
particular span.
You can also hide threads to focus on specific threads. Using the row
labels, select the threads you want to hide. Open the context menu for
the selection, and choose Hide. The graph for these is hidden threads
and does not contribute to the analysis performed for graph or reports.
The calculations in the Threads view are adjusted to reflect only the
visible threads.
The report section, shown here, appears at the bottom of the graph in the Threads view.
The first tab is the Profile Report. The Profile Report can present
different reports based on the category selected in the Visible Timeline
Profile. The default report is the Per-Thread Summary report. Select
Execution in the Visible Timeline Profile to see the Execution Profile
report. Select the Synchronization category for the Synchronization
Blocking Profile report, and so on. The Sleep Blocking Profile is shown
in the next image. This report displays a sampling showing when methods
are in a sleep state. The Inclusive Blocking column includes sampling
for both the selected method and its calling methods. The Exclusive
Blocking column shows the sampling for that method alone. In the
following report, the last method contributes the entire sampling,
because the Inclusive Blocking and Exclusive Blocking columns are
identical.
The Current Stack tab shows the call stack of the selected segment in
the Threads View graph. If you select a different segment, the call
stack is updated to reflect that. The Current Stack report might display
addition information; the category of the selected segment sets the
context for this information. For example, the report for a preemption
segment, as shown here, explains the type of synchronization and length
of delay.
The
Unblocking Stack tab is helpful in finding a deadlock. When the
category of the segment is Synchronization, switch to the Unblocking
Stack tab to view the call stack of the competing thread that controls
the synchronization.